﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Collections.Specialized;
using System.IO;
using System.Threading;
namespace MsgSendAndReceive
{
    internal class TransData
    {
        private TcpListener listen;
        private int tcpPort;
        private Dictionary<int,TcpClient> dicTcpclient=new  Dictionary<int,TcpClient>();
        private int tcpClientID = 0;//定义TCP连接ID
        internal event Action<object, MsgEventArgs> newMessage;
        private TransData()
        {
        }
        private ManualResetEvent allDone = new ManualResetEvent(true);
        public TransData(int port)
        {
            if (port >= 1000)
                tcpPort = port;
            else
                tcpPort = 60000;
            buff = new byte[bufferLength];
            listen = new TcpListener(IPAddress.Loopback,tcpPort);
            Thread mythread = new Thread(new ThreadStart(doAcceptConnection));
            mythread.Start();
        }
        private int bufferLength = 1024;
        private byte[] buff;
        private void  doAcceptConnection()
        {
            listen.Start();
            mylog.AppendStr("开始监听，监听IP：" + IPAddress.Loopback + ",监听端口：" + tcpPort.ToString());
            while (true)
            {
                TcpClient newTcpClient = listen.AcceptTcpClient();
                dicTcpclient.Add(tcpClientID, newTcpClient);
                Thread mythread = new Thread(new ParameterizedThreadStart(doSendAndReceive));
                mythread.Start((object)tcpClientID);
                tcpClientID++;
            }
        }
        private void doSendAndReceive(object obj)
        {
            int tcpID=(int)obj;
            TcpClient client = dicTcpclient[tcpID];
            IPEndPoint ipep=(IPEndPoint)client.Client.RemoteEndPoint;
            mylog.AppendStr("建立新的连接，对端IP地址是："+ipep.Address.ToString()+",对端端口是："+ipep.Port.ToString());
            NetworkStream ns = client.GetStream();
            if (ns.CanRead)
            {
                ns.BeginRead(buff, 0, bufferLength, new AsyncCallback(ReadAsyncCallBack), tcpID);
                
            }
            allDone.WaitOne();
           /* while (client.Connected)
            {
                StreamReader sr = new StreamReader(ns);               
                string str = sr.ReadLine();
                if (newMessage != null)
                {
                    MsgEventArgs e = new MsgEventArgs();
                    e.ID = tcpID;
                    e.msg = str;
                    newMessage(tcpID, e);
                }
                Thread.Sleep(30);
            }*/
        }
        public void ReadAsyncCallBack(IAsyncResult result)
        {
            int tcpID =(int)(result.AsyncState);
            mylog.AppendStr("endread,连接ID："+tcpID.ToString());
            TcpClient client=dicTcpclient[tcpID];
            NetworkStream ns = dicTcpclient[tcpID].GetStream();
            byte[] msgData=new byte[bufferLength];
           // NetworkStream ns = (NetworkStream)result.AsyncState;
            int recvLength;
            if (client != null && client.Connected)
            {
                lock (ns)
                {
                    recvLength = ns.EndRead(result);
                }
                if (recvLength > 0)
                {
                    Array.Copy(buff, msgData, recvLength);
                    string str = "";
                    str = Encoding.ASCII.GetString(msgData, 0, recvLength);

                    if (newMessage != null)
                    {
                        MsgEventArgs e = new MsgEventArgs();
                        e.ID = tcpID;
                        e.msg = str;
                        newMessage(tcpID, e);
                    }
                    lock (ns)
                    {
                        ns.BeginRead(buff, 0, bufferLength, new AsyncCallback(ReadAsyncCallBack), tcpID);
                    }
                }
                else if (recvLength < 1)
                {
                    mylog.AppendStr("连接已经接收不到数据:" + tcpID.ToString());
                    mylog.AppendStr("连接已经断开:" + tcpID.ToString());
                    ns.Close();
                    client.Close();
                    dicTcpclient.Remove(tcpID);
                    mylog.AppendStr("当前在线连接数：" + dicTcpclient.Count.ToString());
                }

            }
            else
            {
                mylog.AppendStr("连接已经断开:" + tcpID.ToString());
                ns.Close();
                client.Close();
                dicTcpclient.Remove(tcpID);
                mylog.AppendStr("当前在线连接数："+dicTcpclient.Count.ToString());
            }
        }
        public bool sengMsg(MsgEventArgs e)
        {
            TcpClient client=dicTcpclient[e.ID];
            if (client == null)
                return false;
            NetworkStream ns = client.GetStream();
            StreamWriter sw = new StreamWriter(ns);
            sw.WriteLine(e.msg);
            sw.Flush();
            sw.Close();         
            return true;
        }

    }
    public class MsgEventArgs : EventArgs
    {
        public int ID;
        public string msg;
    }
    public class mylog
    {
        private static EasyLog.Log Mylog = new EasyLog.Log(@"E:\workspace\Visual Studio 2012\Projects\CmdControl\log.txt",
            EasyLog.LogLevel.LogLevel_Debug,
            "MsgSendAndReceive");
        public static void AppendStr(string str)
        {
            Mylog.AppendStr(str);
        }

    }
}
